package model

import (
	"errors"
	"gopkg.in/mgo.v2/bson"
	"src/config"
	newtime "src/util/time"
)

type Application struct {
	Id              bson.ObjectId `bson:"_id,omitempty" json:"id,omitempty"`
	Status          int           `bson:"status" json:"status"`
	Recommed_userid string        `bson:"recommed_userid" json:"recommed_userid"`
	Recommed_type   int           `bson:"recommed_type" json:"recommed_type"`
	User_id         string        `bson:"user_id" json:"user_id"`
	Forumpost_id    string        `bson:"forumpost_id" json:"forumpost_id"`
	Issue_time      int64         `bson:"issue_time" json:"issue_time"`
	Content         string        `bson:"content" json:"content"`
}

func CreateApplication(a Application) (Application, error) {
	query := bson.M{
		"_id":    bson.ObjectIdHex(a.Forumpost_id),
		"status": config.ForumPostCommonStatus,
	}
	forumpost, err := findForumPost(query, DefaultSelector)
	if err != nil {
		return Application{}, errors.New("forumpost" + err.Error())
	}
	a.User_id = forumpost.UserID
	query = bson.M{
		"forumpost_id":    a.Forumpost_id,
		"recommed_userid": a.Recommed_userid,
	}
	_, err = findApplication(query, DefaultSelector)
	if err == nil {
		return Application{}, config.ErrorHasExist
	}
	query1 := bson.M{
		"forumpost_id":    a.Forumpost_id,
		"recommed_userid": a.Recommed_userid,
	}
	a.Issue_time = newtime.GetMilliTimestamp()
	a.Status = config.ApplicationNewStatus
	err = insertApplication(a)
	if err != nil {
		return Application{}, errors.New("application insert" + err.Error())
	}
	return findApplication(query1, DefaultSelector)
}

func GetApplication() ([]Application, error) {
	query := bson.M{
		"status": config.ApplicationNewStatus,
	}
	return findApplicationsALL(query)
}

func GetApplicationByForumpost(id string) (Application, error) {
	if !bson.IsObjectIdHex(id) {
		return Application{}, config.ErrorIDFormatWrong
	}
	query := bson.M{
		"_id": bson.ObjectIdHex(id),
	}
	return findApplication(query, DefaultSelector)
}

func ReadApplication(id string) error {
	query := bson.M{
		"_id": bson.ObjectIdHex(id),
	}
	update := bson.M{
		"$set": bson.M{
			"status": config.ApplicationReadStatus,
		},
	}
	return updateApplication(query, update)

}

/*********************************************************************/
func updateApplication(query, update interface{}) error {
	sess := globalSess.Clone()
	defer sess.Close()
	ApplicationTable := sess.DB(DBNAME).C(APPLICATIONTABLE)

	return ApplicationTable.Update(query, update)
}
func insertApplication(docs ...interface{}) error {
	sess := globalSess.Clone()
	defer sess.Close()
	ForumPostTable := sess.DB(DBNAME).C(APPLICATIONTABLE)

	return ForumPostTable.Insert(docs...)
}
func findApplication(query, selector interface{}) (Application, error) {
	sess := globalSess.Copy()
	defer sess.Close()
	ApplicationTable := sess.DB(DBNAME).C(APPLICATIONTABLE)

	Application := Application{}
	err := ApplicationTable.Find(query).Select(selector).One(&Application)
	return Application, err
}

func findApplications(query, selector interface{}, page, perPage int, fields ...string) ([]Application, error) {
	sess := globalSess.Copy()
	defer sess.Close()
	ApplicationTable := sess.DB(DBNAME).C(APPLICATIONTABLE)

	Applications := []Application{}
	err := ApplicationTable.Find(query).Select(selector).Sort(fields...).Skip((page - 1) * perPage).Limit(perPage).All(&Applications)
	return Applications, err
}
func findApplicationsALL(query interface{}) ([]Application, error) {
	sess := globalSess.Copy()
	defer sess.Close()
	ApplicationTable := sess.DB(DBNAME).C(APPLICATIONTABLE)

	Applications := []Application{}
	err := ApplicationTable.Find(query).All(&Applications)
	return Applications, err
}
